package com.ioudi.digu.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ioudi.digu.dao.support.IQuerySupport;
import com.ioudi.digu.service.support.ListResult;
import com.ioudi.digu.vo.FriendShip;

public class FriendshipDAO extends HibernateDaoSupport
{	
	private IQuerySupport querySupport;
	
    public IQuerySupport getQuerySupport()
	{
		return querySupport;
	}

	public void setQuerySupport(IQuerySupport querySupport)
	{
		this.querySupport = querySupport;
	}

	public boolean saveFriendship(FriendShip ship)
    {
    	 Session s = this.getSession();
    	 boolean result = false;
         try
         {
         	s.beginTransaction();
         	s.merge(ship);
         	s.getTransaction().commit();
         	result = true;
         }
         catch(Exception e)
         {
         	s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return result;
    }
    
    public boolean removeFriendship(String user, String friend)
    {
    	 Session s = this.getSession();
    	 boolean result = false;
         try
         {
         	s.beginTransaction();
         	s.createQuery("delete FriendShip ship where ship.user.account =? and ship.friend.account=?").
         	    setString(0, user).setString(1, friend).executeUpdate();
         	s.getTransaction().commit();
         	result = true;
         }
         catch(Exception e)
         {
         	s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return result;
    }
    
    public FriendShip getFriendship(String user, String friend)
    {
    	 Session s = this.getSession();
    	 FriendShip ship = null;
         try
         {
         	s.beginTransaction();
         	Object result = s.createQuery("from FriendShip ship where ship.user.account =? and ship.friend.account=?").
         	    setString(0, user).setString(1, friend).uniqueResult();
         	if(result != null)
         	{
         		ship = (FriendShip)result;
         	}
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	ship = null;
         	s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return ship;
    }
    
    public boolean hasFriend(String user, String friend)
    {
    	 Session s = this.getSession();
    	 Object result;
         try
         {
         	s.beginTransaction();
         	result = s.createQuery("select count(ship) " +
         			"from FriendShip ship where ship.user.account =? and ship.friend.account=?").
         	    setString(0, user).setString(1, friend).uniqueResult();
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	 result = false;
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return result != null ? ((Long)result).intValue() != 0 : false;
    }
    
    /**
     * This is a special method, support MessageSelector.it's used internally
     */
    public List getFollowerIds(int index, int maxCount, Map<String, Object> condition)
    {
     	 Session s = this.getSession();
    	 List<String> result = null;
         try
         {
         	s.beginTransaction();
         	List<Object> values = new ArrayList<Object>();
         	String sql = "select ship.user.account from FriendShip ship where ship.friend.user=? ";
         	values.add(condition.get("user"));
         	if(condition != null)
         	{
         		if(condition.get("MessageSelector#showReplyMessage") != null)
         		{
         			sql += " and ship.user.account in (" +
         					"select selector.user from MessageSelector as selector where selector.showReplyMessage = ?" +
         					")";
         			values.add(condition.get("MessageSelector#showReplyMessage"));
         		}
         		if(condition.get("Friendship#mutualFriend") != null)
         		{
         			sql += " and ship.user.account in (" +
         					"select fs.friend.account from FriendShip  fs where fs.user.account = ? " +
         					")";
         			values.add(condition.get("user"));
         		}
         	}
         	Query query = s.createQuery(sql);
         	int valuesIndex = values.size() -1;
         	Object value;
         	while(valuesIndex >= 0)
         	{
         		value = values.get(valuesIndex);
         		if(value instanceof String)
         		{
         			query.setString(valuesIndex, String.valueOf(value));
         		}
         		else if(value instanceof Boolean)
         		{
         			query.setBoolean(valuesIndex, (Boolean)value);
         		}
         		valuesIndex--;
         	}
         	result = query.list();
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return result;
    }
    

    public ListResult getFollowers(int index, int maxCount, Map<String, Object> condition)
    {
    	 Session s = this.getSession();
    	 ListResult listResult = null;
         try
         {
         	s.beginTransaction();
         	listResult = new ListResult();
         	List<String> keys = new ArrayList<String>();
         	String sql = "from FriendShip ship";
         	String where = querySupport.createStatement("ship.friend", condition, keys);
         	sql += where.length() > 0 ? " where " + where : "";
         	Query query = s.createQuery("select count(ship) " + sql);
         	Object result = querySupport.createQuery(query, keys, condition).uniqueResult();
         	if(result != null)
         	{
         		listResult.setTotal(((Long)result).intValue());
         	}
         	query  = s.createQuery("select ship.user " + sql);
         	query.setFirstResult(index);
         	if(maxCount > 0)
         	{
         		query.setMaxResults(maxCount);
         	}
         	listResult.setContents(querySupport.createQuery(query, keys, condition).list());
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	 listResult = null;
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return listResult;
    }
    
    public ListResult getFriends(int index, int maxCount, Map<String, Object> condition)
    {
    	 Session s = this.getSession();
    	 ListResult listResult = null;
         try
         {
         	s.beginTransaction();
         	listResult = new ListResult();
         	List<String> keys = new ArrayList<String>();
         	String sql = "from FriendShip ship";
         	String where = querySupport.createStatement("ship", condition, keys);
         	where = where.replaceFirst("account", "user.account");
         	sql += where.length() > 0 ? " where " + where : "";
         	Query query = s.createQuery("select count(ship) " + sql);
         	Object result = querySupport.createQuery(query, keys, condition).uniqueResult();
         	if(result != null)
         	{
         		listResult.setTotal(((Long)result).intValue());
         	}
         	query  = s.createQuery("select ship.friend " + sql);
         	query.setFirstResult(index);
         	if(maxCount > 0)
         	{
         		query.setMaxResults(maxCount);
         	}
         	listResult.setContents(querySupport.createQuery(query, keys, condition).list());
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	 listResult = null;
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return listResult;
    }
    
    public List checkFriends(String user, List others)
    {
    	 Session s = this.getSession();
    	 List list = null;
         try
         {
         	s.beginTransaction();
         	String sql = "select ship.friend.account from FriendShip ship where ship.user.account = ? and ship.friend.account in (:ids)" ;
         	Query query = s.createQuery(sql);
         	query.setString(0, user);
         	query.setParameterList("ids", others);
         	list = query.list();
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	 list = null;
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return list;
    }
    
    public ListResult getFriendships(String user, int index, int maxCount, Map<String, Object> condition)
    {
    	 Session s = this.getSession();
    	 ListResult listResult = null;
         try
         {
         	s.beginTransaction();
         	listResult = new ListResult();
         	List<String> keys = new ArrayList<String>();
         	String sql = "select count(ship) from FriendShip ship where  ship.user=? and ";
         	String where = querySupport.createStatement("ship", condition, keys);
         	sql += where;
         	Query query = s.createQuery(sql);
         	keys.add(0, user);
         	condition.put("user", user);
         	Object result = querySupport.createQuery(query, keys, condition).uniqueResult();
         	if(result != null)
         	{
         		listResult.setTotal(((Long)result).intValue());
         	}
         	sql = "from FriendShip ship where ship.user=? and ";
         	query  = s.createQuery(sql + where);
         	query.setFirstResult(index);
         	if(maxCount > 0)
         	{
         		query.setMaxResults(maxCount);
         	}
         	listResult.setContents(querySupport.createQuery(query, keys, condition).list());
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
        	 listResult = null;
         	 s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return listResult;
    }
    
    public List getGroupNames(String user)
    {
    	 Session s = this.getSession();
    	 List result = null;
         try
         {
         	s.beginTransaction();
         	result = s.createQuery("select ship.groupName from FriendShip ship where ship.user=?").
         	    setString(0, user).list();
         	s.getTransaction().commit();
         }
         catch(Exception e)
         {
         	s.getTransaction().rollback();
         }
         finally
         {
         	s.close();
         }
     	return result;
    }
}
